from django.core.mail import send_mail
from rest_framework import serializers
from users.models import User
import re
from django_redis import get_redis_connection
from rest_framework_jwt.settings import api_settings
from django.conf import settings
# from celery_tasks.email_celery.tasks import send_email
from itsdangerous import TimedJSONWebSignatureSerializer as TJS
from goods.models import SKU
from django_redis import get_redis_connection


class UserSerializer(serializers.ModelSerializer):
    password2 = serializers.CharField(min_length=8, max_length=20, write_only=True)
    sms_code = serializers.CharField(min_length=6, max_length=20, write_only=True)
    allow = serializers.CharField(write_only=True)
    token = serializers.CharField(read_only=True)

    class Meta:
        model = User
        fields = ('id', 'username', 'password', 'password2', 'sms_code', 'mobile', 'allow', 'token')
        extra_kwargs = {
            'username': {
                'min_length': 5,
                'max_length': 20,
                'error_messages': {
                    'min_length': '名字过短',
                    'max_length': '名字过长'
                }
            },
            'password': {
                'write_only': True,
                'min_length': 8,
                'max_length': 20,
                'error_messages': {
                    'min_length': '密码过短',
                    'max_length': '密码过长'
                }
            },

        }

    def validate_mobile(self, value):
        if not re.match(r'^1[3-9]\d{9}$', value):
            return serializers.ValidationError('格式错误')
        return value

    def validate_allow(self, value):
        if value != 'true':
            return serializers.ValidationError('请勾选同意协议')
        return value

    def validate(self, attrs):
        # 判断两次的密码是否一致
        if attrs['password'] != attrs['password2']:
            return serializers.ValidationError('两次密码不一致')
        conn = get_redis_connection('verify')
        real_sms_code = conn.get('sms_code_%s' % attrs['mobile']).decode()

        if not real_sms_code:
            return serializers.ValidationError('验证码已过期')

        if attrs['sms_code'] != real_sms_code:
            return serializers.ValidationError('验证码输入不正确')
        return attrs

    def create(self, validated_data):
        del validated_data['password2']
        del validated_data['allow']
        del validated_data['sms_code']
        print(validated_data)

        user = super().create(validated_data)

        user.set_password(validated_data['password'])
        user.save()

        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        # 写入token
        user.token = token
        return user


class UserDeatilSerialier(serializers.ModelSerializer):
    """用户详情信息序列化器"""

    class Meta:
        model = User
        fields = ('id', 'username', 'mobile', 'email', 'email_active')


class UserEmailSerializser(serializers.ModelSerializer):
    """
    邮箱序列化器
    """

    class Meta:
        model = User
        fields = ('id', 'email')
        extra_kwargs = {
            'email': {
                'required': True
            }
        }

    #

    def update(self, instance, validated_data):
        email = validated_data['email']
        instance.email = email
        instance.save()

        tjs = TJS(settings.SECRET_KEY, 300)
        token = tjs.dumps({'id': instance.id, 'username': instance.username}).decode()

        # send_mail('美多商城邮箱验证','',settings.EMAIL_FROM,['478875130@qq.com'],html_message='<a href="https://www.baidu.com">百度</a>')
        verify_url = 'http://www.meiduo.site:8080/success_verify_email.html?token=' + token
        to_email = email
        subject = '美多商城邮箱验证'
        html_message = '<p>尊敬的用户您好！</p>' \
                       '<p>感谢您使用美多商城。</p>' \
                       '<p>您的邮箱为：%s 。请点击此链接激活您的邮箱：</p>' \
                       '<p><a href="%s">%s<a></p>' % (to_email, verify_url, verify_url)

        send_mail(subject, '', settings.EMAIL_FROM, [to_email], html_message=html_message)
        # send_email.delay(token, email)
        return instance


class VerifyEmailSerializer(serializers.Serializer):
    """验证token值是否正确"""
    token = serializers.CharField(write_only=True)

    def validate(self, attrs):
        # print('序列化器中的token值',attrs['token'])
        # token解密
        tjs = TJS(settings.SECRET_KEY, 300)
        try:
            data = tjs.loads(attrs['token'])
            # print('解密后的token值',data)
        except:
            raise serializers.ValidationError('错误的token值')

        if not data:
            raise serializers.ValidationError('无效的token值')
        # 解密后的token值
        attrs['data'] = data
        # print(attrs)
        return attrs


class AddUserHistorySerializer(serializers.Serializer):
    """添加用户浏览历史序列化器"""
    sku_id = serializers.IntegerField(label='商品编号', min_value=1)

    def validate(self, attrs):
        """检验前端传过来的sku_id是否存在"""
        try:
            SKU.objects.get(id=attrs['sku_id'])
        except:
            raise serializers.ValidationError('sku_id不存在')

        return attrs

    def create(self, validated_data):
        """保存到redis中"""
        user_id = self.context['request'].user.id
        sku_id = validated_data['sku_id']

        conn = get_redis_connection('history')
        pl = conn.pipeline()

        # 移除所有重复的sku_id  就是一个用户可能会浏览同一个商品,这样就没必要保存多份了
        pl.lrem('history_%s' % user_id, 0, sku_id)

        # 添加新的浏览记录
        pl.lpush('history_%s' % user_id, sku_id)

        # 只保存最新的5条数据
        pl.ltrim('history_%s' % user_id, 0, 4)

        pl.execute()

        return validated_data
